package pers.xiaojun.boot.common.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import lombok.SneakyThrows;
import pers.xiaojun.boot.common.biz.system.dict.DictCommonApi;
import pers.xiaojun.boot.common.biz.system.dict.dto.DictDataRespDTO;

import java.time.Duration;
import java.util.List;
import java.util.Objects;

/**
 * 字典工具类
 *
 * @author xiaojun
 * @since 2025-11-08
 */
public class DictUtils {

    private static final DictCommonApi dictCommonApi;
    private static final LoadingCache<String, List<DictDataRespDTO>> dictDataCache;

    static {
        dictCommonApi = SpringUtil.getBean(DictCommonApi.class);
        dictDataCache = buildDictDataCache();
    }

    private static LoadingCache<String, List<DictDataRespDTO>> buildDictDataCache() {
        return CacheUtils.buildAsyncReloadingCache(
                Duration.ofMinutes(1),
                new CacheLoader<>() {
                    @Override
                    public List<DictDataRespDTO> load(String key) {
                        return dictCommonApi.listDictDatasByDictType(key);
                    }
                }
        );
    }

    /**
     * 根据字典类型和标签获取字典值
     *
     * @param dictType 字典类型
     * @param label    字典标签
     * @return 字典键值
     */
    @SneakyThrows
    public static String getDictValue(String dictType, String label) {
        List<DictDataRespDTO> dictDataList = dictDataCache.get(dictType);

        return dictDataList.stream()
                .filter(dict -> Objects.equals(dict.getLabel(), label))
                .map(DictDataRespDTO::getValue)
                .findFirst().orElse(null);
    }

    /**
     * 根据字典类型和字典键值获取标签
     *
     * @param dictType 字典类型
     * @param value    字典键值
     * @return 典标签
     */
    @SneakyThrows
    public static String getDictLabel(String dictType, String value) {
        List<DictDataRespDTO> dictDataList = dictDataCache.get(dictType);

        return dictDataList.stream()
                .filter(dict -> Objects.equals(dict.getValue(), value))
                .map(DictDataRespDTO::getLabel)
                .findFirst().orElse(null);
    }

}
